<template>
  <FormItem v-bind="formItemProps" :rules="computeRules" :disabled="inputDisabled">
    <template #default>
      <slot>
        <VueTreeSelect
          :class="['form-tree-select', { 'is-readonly': readonly }]"
          :value="value"
          :readonly="readonly"
          :disabled="inputDisabled"
          :default-expand-level="0"
          :placeholder="inputDisabled ? '' : computePlaceholder"
          v-bind="inputProps"
          :normalizer="normalizer"
          v-on="listeners"
          @input="emitInput">
          <template #value-label="{ node }">
            <slot name="value-label" :node="node">{{ node.label }}</slot>
          </template>
        </VueTreeSelect>
        <div v-if="isValidValue && $slots.warn" class="el-form-item__warn">
          <slot name="warn"></slot>
        </div>
      </slot>
    </template>
    <template #error="{ error }">
      <div v-if="$scopedSlots.error && $scopedSlots.error(error)" class="el-form-item__error">
        <slot name="error" :error="error">{{ error }}</slot>
      </div>
    </template>
    <template #label>
      <slot name="label"></slot>
    </template>
    <template #tips>
      <slot name="tips"></slot>
    </template>
  </FormItem>
</template>

<script>
  import formInput from './form-input'
  import { filterProperties, normalizeProps, validateProp } from '@/util'
  import { VueTreeSelect } from '@web-utils/component'

  const autoBindKeys = Object.keys(VueTreeSelect.mixins[0].props).filter(
    key => !['value', 'placeholder', 'disabled'].includes(key)
  )

  export default {
    name: 'FormTreeSelect',
    mixins: [formInput],
    props: {
      value: [String, Number]
    },
    data() {
      return {
        isValidValue: false
      }
    },
    computed: {
      inputProps() {
        return filterProperties({ ...normalizeProps(this.$attrs), ...this.$props }, autoBindKeys)
      }
    },
    watch: {
      async value(newVal) {
        this.isValidValue = await validateProp(this.prop, newVal, this.computeRules)
      }
    },
    methods: {
      normalizer(node) {
        if (node.children && !node.children.length) {
          delete node.children
        }
        return {
          id: node.id,
          label: node.name,
          isDisabled: false,
          children: node.children
        }
      },
      emitInput(val) {
        this.$emit('input', val)
      }
    }
  }
</script>

<style lang="scss">
  @import '@/assets/styles/theme-default/form-tree-select';
</style>
